package org.micro.test.core.servlet;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.micro.test.core.Constants;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * The Micro Page Http Servlet
 *
 * @author lry
 */
@Slf4j
public class PageHttpServlet extends HttpServlet {

    private Map<String, String> htmlCaches = new ConcurrentHashMap<>();
    private Map<String, String> cssCaches = new ConcurrentHashMap<>();
    private Map<String, String> jsCaches = new ConcurrentHashMap<>();
    private Map<String, BufferedImage> pngCaches = new ConcurrentHashMap<>();
    private Map<String, byte[]> woffCaches = new ConcurrentHashMap<>();


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        String path = request.getRequestURI();
        if (path.endsWith(".css")) {
            this.getCSS(request, response);
        } else if (path.endsWith(".js")) {
            this.getJS(request, response);
        } else if (path.endsWith(".png")) {
            this.getPNG(request, response);
        } else if (path.endsWith(".woff")) {
            this.getFont(request, response);
        } else {
            this.getHtml(request, response);
        }
    }

    private void getCSS(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader(Constants.CONTENT_TYPE, "text/css; charset=UTF-8");
        String path = request.getRequestURI();
        path = path.substring(path.indexOf("/html/"));

        String context = cssCaches.get(path);
        if (context == null) {
            cssCaches.put(path, context = IOUtils.resourceToString(path, StandardCharsets.UTF_8));
        }

        response.getWriter().print(context);
    }

    private void getJS(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader(Constants.CONTENT_TYPE, "application/x-javascript; charset=UTF-8");
        String path = request.getRequestURI();
        path = path.substring(path.indexOf("/html/"));

        String context = jsCaches.get(path);
        if (context == null) {
            jsCaches.put(path, context = IOUtils.resourceToString(path, StandardCharsets.UTF_8));
        }

        response.getWriter().print(context);
    }

    private void getPNG(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader(Constants.CONTENT_TYPE, "image/png; charset=UTF-8");
        String path = request.getRequestURI();
        path = path.substring(path.indexOf("/html/"));

        BufferedImage bufferedImage = pngCaches.get(path);
        if (bufferedImage == null) {
            InputStream inputStream = IOUtils.resourceToURL(path).openStream();
            pngCaches.put(path, bufferedImage = ImageIO.read(inputStream));
        }

        ImageIO.write(bufferedImage, "png", response.getOutputStream());
    }

    private void getFont(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader(Constants.CONTENT_TYPE, "application/font-woff; charset=UTF-8");
        String path = request.getRequestURI();
        path = path.substring(path.indexOf("/html/"));

        byte[] data = woffCaches.get(path);
        if (data == null) {
            woffCaches.put(path, data = IOUtils.resourceToByteArray(path));
        }

        response.getOutputStream().write(data);
    }


    private void getHtml(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader(Constants.CONTENT_TYPE, "text/html;charset=UTF-8");
        String path = request.getRequestURI();
        if (path.endsWith(Constants.PAGE_API_URL)) {
            String context = htmlCaches.get(path);
            if (context == null) {
                htmlCaches.put(path, context = IOUtils.resourceToString(Constants.API_PATH, StandardCharsets.UTF_8));
            }
            response.getWriter().print(context);
        }
    }

}